home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / smaltalk.lha / smalltalk-1.1.1 / mstmain.c < prev    next >
C/C++ Source or Header  |  1991-09-14  |  21KB  |  800 lines

  1. /***********************************************************************
  2.  *
  3.  *    Main Module
  4.  *
  5.  ***********************************************************************/
  6.  
  7. /***********************************************************************
  8.  *
  9.  * Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  10.  * Written by Steve Byrne.
  11.  *
  12.  * This file is part of GNU Smalltalk.
  13.  *
  14.  * GNU Smalltalk is free software; you can redistribute it and/or modify it
  15.  * under the terms of the GNU General Public License as published by the Free
  16.  * Software Foundation; either version 1, or (at your option) any later 
  17.  * version.
  18.  * 
  19.  * GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  20.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  21.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  22.  * more details.
  23.  * 
  24.  * You should have received a copy of the GNU General Public License along with
  25.  * GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  26.  * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  27.  *
  28.  ***********************************************************************/
  29.  
  30.  
  31. /*
  32.  *    Change Log
  33.  * ============================================================================
  34.  * Author      Date       Change 
  35.  * sbb         12 Sep 91      Fxied -I argument parsing code to properly gobble up
  36.  *              the file name.
  37.  *
  38.  * sbyrne    22 May 90      Improved on Doug's mapping with macro to improve
  39.  *              readability.
  40.  *
  41.  * sbyrne    22 May 90      Short name stuff added, thanks to Doug McCallum.
  42.  *
  43.  * sbyrne    25 Mar 90      ProcessorScheduler is too long of a name for the
  44.  *              Atari; there are uniqueness problems.  Shortened to
  45.  *              ProcScheduler.   Also, fixed quietExecution; wasn't
  46.  *              set when reading from the terminal; should have been
  47.  *              set to false (since the loading of the quiet things
  48.  *              is over).
  49.  *
  50.  * sbyrne    15 Oct 89      Added support for creating an "installed" version of
  51.  *              Smalltalk.  There is now an include file that the
  52.  *              installer can customize for his site that provides
  53.  *              default locations to be checked for the kernel .st
  54.  *              files and the binary image file, but these can be
  55.  *              overidden in two ways: a) by a file of the same
  56.  *              name in the user's current directory, or b)
  57.  *              environment variables SMALLTALK_KERNEL and
  58.  *              SMALLTALK_IMAGE.
  59.  *
  60.  * sbyrne     4 Jul 89      Added support for user init files (in ~/.stinit),
  61.  *              which are invoked on every startup.  Also, added
  62.  *              support for initBlocks, which are blocks that are
  63.  *              stored in the system and invoked on each startup
  64.  *              (these could be used, for example, as an interim
  65.  *              measure for declaring C callouts until the callout
  66.  *              descriptor is converted to a Smalltalk object).
  67.  *
  68.  * sbyrne    10 Mar 89      Added support for automatically loading image file if
  69.  *              it's newer than and of the system source files.
  70.  *
  71.  * sbyrne    27 Dec 88      Created.
  72.  *
  73.  */
  74.  
  75.  
  76. #include "mst.h"
  77. #include "mst.tab.h"
  78. #include "mstinterp.h"
  79. #include "mstcomp.h"
  80. #include "mstsave.h"
  81. #include "mstsym.h"        /* for symbol table profiling */
  82. #include "mstoop.h"        /* indirectly defines oopAt for sym tab prof */
  83. #include "mstpaths.h"
  84. #include "mstmain.h"
  85. #include <stdio.h>
  86. #include <sys/types.h>
  87. #include <sys/stat.h>
  88. #include <sys/file.h>
  89. #if defined(USG)
  90. #include <unistd.h>
  91. #endif
  92.  
  93. #ifndef MAXPATHLEN
  94. #define MAXPATHLEN        1024 /* max length of a file and path */
  95. #endif
  96.  
  97. #ifdef SHORTNAMES
  98. #define MAP_FILE(long, short)    short
  99. #else
  100. #define MAP_FILE(long, short)    long
  101. #endif
  102.  
  103.  
  104. #ifndef atarist
  105. #define INIT_FILE_NAME        ".stinit"
  106. #else
  107. #define INIT_FILE_NAME        ".tinit"
  108. #endif
  109.  
  110.  
  111. extern int        yydebug, lexDebug, numFreeOOPs;
  112. extern YYSTYPE        yylval;
  113. extern char        *getenv();
  114.  
  115. #ifdef symbol_table_profiling
  116. extern int        adds, reused, reprobes, hitsOn[];
  117. #endif /* symbol_table_profiling */
  118.  
  119. /* When true, this flag suppresses the printing of execution-related
  120.  * messages, such as the number of byte codes executed by the
  121.  * last expression, etc.
  122.  */
  123. Boolean            quietExecution;
  124.  
  125. char            *kernelFileDefaultPath, *imageFileDefaultPath;
  126.  
  127. /* This string contains the printed representation of the Smalltalk version
  128.  * number
  129.  */
  130. char            versionString[50];
  131.  
  132. static Boolean         processFile(), okToLoadBinary();
  133. static void        loadStandardFiles(), loadUserInitFile(), initPaths(),
  134.             findKernelFile(), parseArgs(), makeVersionString();
  135. static unsigned long    getFileModifyTime();
  136.  
  137.  
  138. /* Set by cmd line flag.  If true, Smalltalk is more verbose about what it's
  139.  * doing.
  140.  */
  141. static Boolean        verbose = false;
  142.  
  143. /* If true, even both kernel and user method definitions are shown as
  144.  * they are compiled.
  145.  */
  146. static Boolean        traceKernelDeclarations;
  147.  
  148. /* If true, execution tracing is performed when loading kernel method
  149.  * definitions
  150.  */
  151. static Boolean        traceKernelExecution;
  152.  
  153. /* If true, skip date checking of kernel files vs. binary image; pretend
  154.  * that binary image does not exist
  155.  */
  156. static Boolean        ignoreImage;
  157.  
  158.  
  159. /* If non-nil, this is the name of the binary image to load, and overrides
  160.  * the checking of the dates of the kernel source files against the image
  161.  * file date.
  162.  */
  163. static char        *binaryImageName = nil;
  164.  
  165.  
  166. /* Set by command line flag.  When this is true, the interpreter 
  167.  * does not print out things like "execution begins" or information
  168.  * about the number of byte codes executed.
  169.  */
  170. static Boolean        runQuietly = false;
  171.  
  172.  
  173. /* The complete list of "kernel" class and method definitions.  Each of
  174.  * these files is loaded, in the order given below.  Their last modification
  175.  * dates are compared against that of the image file; if any are newer,
  176.  * the image file is ignored, these files are loaded, and a new image file
  177.  * is created.
  178.  */
  179. static char        *standardFiles[] = {
  180.   "builtins.st", 
  181.   "Object.st",
  182.   "Message.st",
  183.   "Magnitude.st",
  184.   "Character.st",
  185.   "Date.st",
  186.   "Time.st",
  187.   "Number.st",
  188.   "Float.st",
  189.   "Integer.st",
  190.   "LookupKey.st",
  191.   "Association.st",
  192.   "Link.st",
  193.   "Process.st",
  194.   "Collection.st",
  195.   MAP_FILE("SequenceableCollection.st", "SeqColl.st"),
  196.   "LinkedList.st",
  197.   "Semaphore.st",
  198.   MAP_FILE("ArrayedCollection.st", "ArrColl.st"),
  199.   "Array.st",
  200.   "String.st",
  201.   "Symbol.st",
  202.   "ByteArray.st",
  203.   MAP_FILE("CompiledMethod.st", "CompileMth.st"),
  204.   "Interval.st",
  205.   MAP_FILE("OrderedCollection.st", "OrdColl.st"),
  206.   MAP_FILE("SortedCollection.st", "SortedColl.st"),
  207.   "Bag.st",
  208.   MAP_FILE("MappedCollection.st", "MappedColl.st"),
  209.   "Set.st",
  210.   "Dictionary.st",
  211.   MAP_FILE("IdentityDictionary.st", "IdentDict.st"),
  212.   MAP_FILE("SystemDictionary.st", "SysDict.st"),
  213.   "Stream.st",
  214.   MAP_FILE("PositionableStream.st", "PosStream.st"),
  215.   "ReadStream.st",
  216.   "WriteStream.st",
  217.   MAP_FILE("ReadWriteStream.st", "RWStream.st"),
  218.   "FileStream.st",
  219.   "TokenStream.st",
  220.   "Random.st",
  221.   MAP_FILE("UndefinedObject.st", "UndefObj.st"),
  222.   "Boolean.st",
  223.   "False.st",
  224.   "True.st",
  225. #if !defined(USG) && !defined(atarist)
  226.   "ProcessorScheduler.st",
  227. #else
  228.   "ProcSched.st",
  229. #endif
  230.   "Delay.st",
  231.   "SharedQueue.st",
  232.   "Behavior.st",
  233.   MAP_FILE("ClassDescription.st", "ClassDescr.st"),
  234.   "Class.st",
  235.   "Metaclass.st",
  236.   MAP_FILE("MethodContext.st", "MthContext.st"),
  237.   MAP_FILE("BlockContext.st", "BlkContext.st"),
  238.   "Memory.st",
  239.   "WordMemory.st",
  240.   "ByteMemory.st",
  241.   "MethodInfo.st",
  242.   "FileSegment.st",
  243.   "SymLink.st",
  244.   "initialize.st",
  245.   "CFuncs.st",
  246.   "Autoload.st",
  247.   nil
  248. };
  249.  
  250. #ifdef atarist
  251. long _stksize = -1L;        /* what does this do? */
  252. #endif
  253. main(argc, argv)
  254. int    argc;
  255. char     **argv;
  256. {
  257.   Boolean    loadBinary, traceUserDeclarations, traceUserExecution;
  258.   int        filesProcessed;
  259.   char        *imageName;
  260.  
  261. #ifdef USE_MONCONTROL
  262.   moncontrol(0);        /* don't monitor the initial stuff */
  263. #endif /* USE_MONCONTROL */
  264.  
  265.   yydebug = 0;
  266.   traceKernelDeclarations = declareTracing = false;
  267.   traceKernelExecution = executionTracing = false;
  268.   regressionTesting = false;
  269.   ignoreImage = false;
  270.   verbose = false;
  271.  
  272.   initSignals();
  273.   initMem();
  274.   initCFuncs();
  275.   initPaths();
  276.   makeVersionString();
  277. #if defined(USG)
  278.   tzset();
  279. #endif
  280.  
  281.   parseArgs(argc, argv);
  282.  
  283.   imageName = defaultImageName;
  284.  
  285.   if (binaryImageName) {
  286.     loadBinary = true;
  287.     imageName = binaryImageName;
  288.   } else if (ignoreImage) {
  289.     loadBinary = false;
  290.   } else {
  291.     loadBinary = okToLoadBinary(defaultImageName);
  292.   }
  293.  
  294.   if (loadBinary && loadFromFile(imageName)) {
  295.     initDefaultCompilationEnvironment();
  296.     initSTDIOObjects();
  297.     initInterpreter();
  298.     gcOn();
  299.   } else {
  300.     initOOPTable();
  301.     initDictionary();
  302.     initSymbols();
  303.     initInterpreter();
  304.  
  305.     installInitialMethods();
  306.  
  307.     traceUserDeclarations = declareTracing;
  308.     traceUserExecution = executionTracing;
  309.     if (!traceKernelDeclarations) {
  310.       declareTracing = false;
  311.     }
  312.     if (!traceKernelExecution) {
  313.       executionTracing = false;
  314.     }
  315.  
  316.     gcOn();
  317.     loadStandardFiles();
  318.  
  319.     declareTracing = traceUserDeclarations;
  320.     executionTracing = traceUserExecution;
  321.  
  322. /* ***    gcOn(); *** */
  323.     saveToFile(defaultImageName);
  324.   }
  325.  
  326. #ifdef preserved /* Sun Mar 26 23:36:15 1989 */
  327. /**/#ifdef profiling
  328. /**/  monitor(0);
  329. /**/
  330. /**/  printf("results %d/%d\n", hits, misses);
  331. /**/  { int i;
  332. /**/    for (i = 0; i < 10240; i++) {
  333. /**/      if (hitsOn[i]) {
  334. /**/    printf("hitsOn[%d] = %4d\t%d\t%4x\t%8o", i, hitsOn[i],
  335. /**/           i, i, i);
  336. /**/    printObject(oopAt(i));
  337. /**/    printf("\n");
  338. /**/      }
  339. /**/    }
  340. /**/  }
  341. /**/#endif /* profiling */
  342. #endif /* preserved Sun Mar 26 23:36:15 1989 */
  343.  
  344. #ifdef USE_MONCONTROL
  345.   moncontrol(1);
  346. #endif /* USE_MONCONTROL */
  347.  
  348.   invokeInitBlocks();
  349.   loadUserInitFile();
  350.  
  351. #ifdef symbol_table_profiling
  352.   printf("%d adds, %d reused %d reprobes\n", adds, reused, reprobes);
  353.  
  354.   { int i;
  355.     for (i = 0; i < OOP_TABLE_SIZE; i++) {
  356.       if (hitsOn[i]) {
  357.     printf("hitsOn[%d] = %4d\t%d\t%4x\t%8o", i, hitsOn[i],
  358.            i, i, i);
  359.     printObject(oopAt(i));
  360.     printf("\n");
  361.       }
  362.     }
  363.   }
  364. #endif /* symbol_table_profiling */
  365.  
  366.   if (regressionTesting) {
  367.     printf("Smalltalk Ready\n\n");
  368.   } else {
  369.     printf("Smalltalk %s Ready\n\n", versionString);
  370.   }
  371.  
  372.   quietExecution = runQuietly || emacsProcess;
  373. #ifndef LEXDEBUG
  374.   for (filesProcessed = 0; *++argv; ) {
  375.     if (argv[0][0] != '-') {
  376.       processFile(argv[0], quietExecution);
  377.       filesProcessed++;
  378.     } else if (argv[0][1] == '-' || argv[0][1] == '\0') {
  379.       /* either - by itself or -- indicates standard input */
  380.       initLexer(false);
  381. #ifdef USE_READLINE
  382.       pushReadlineString();
  383. #else
  384.       pushUNIXFile(stdin, "stdin");
  385. #endif /* USE_READLINE */
  386.       yyparse();
  387.       popStream(true);
  388.     }
  389.   }
  390.  
  391.   if (filesProcessed == 0) {    /* didn't do any from cmd line, so read stdin*/
  392.     initLexer(false);
  393. #ifdef USE_READLINE
  394.     pushReadlineString();
  395. #else
  396.     pushUNIXFile(stdin, "stdin");
  397. #endif /* USE_READLINE */
  398.     yyparse();
  399.   }
  400.  
  401. #ifdef USE_MONCONTROL
  402.    moncontrol(0);
  403. #endif /* USE_MONCONTROL */
  404.  
  405. #else /* debugging the lexer */
  406.  
  407. #ifdef USE_READLINE
  408.     pushReadlineString();
  409. #else
  410.     pushUNIXFile(stdin, "stdin");
  411. #endif /* USE_READLINE */
  412.  
  413. /********* THIS IS NOT UP TO DATE ... BEWARE ************/
  414.  
  415.   lexDebug = 1;
  416.   while(!feof(infile)) {
  417.     switch (yylex()) {
  418.     case DOT:
  419.       printf("DOT\n");
  420.       break;
  421.     case BANG:
  422.       printf("BANG\n");
  423.       break;
  424.     case COLON:
  425.       printf("COLON\n");
  426.       break;
  427.     case VERTICAL_BAR:
  428.       printf("VERTICAL_BAR\n");
  429.       break;
  430.     case UPARROW:
  431.       printf("UPARROW\n");
  432.       break;
  433.     case ASSIGN:
  434.       printf("ASSIGN\n");
  435.       break;
  436.     case SHARP:
  437.       printf("SHARP\n");
  438.       break;
  439.     case SEMICOLON:
  440.       printf("SEMICOLON\n");
  441.       break;
  442.     case OPEN_PAREN:
  443.       printf("OPEN_PAREN\n");
  444.       break;
  445.     case CLOSE_PAREN:
  446.       printf("CLOSE_PAREN\n");
  447.       break;
  448.     case OPEN_BRACKET:
  449.       printf("OPEN_BRACKET\n");
  450.       break;
  451.     case CLOSE_BRACKET:
  452.       printf("CLOSE_BRACKET\n");
  453.       break;
  454.     case IDENTIFIER:
  455.       printf("IDENTIFIER: %s\n", yylval.sval);
  456.       break;
  457.     case INTEGER_LITERAL:
  458.       printf("INTEGER_LITERAL: %d\n", yylval.ival);
  459.       break;
  460.     case FLOATING_LITERAL:
  461.       printf("FLOATING_LITERAL: %g\n", yylval.fval);
  462.       break;
  463.     case CHAR_LITERAL:
  464.       printf("CHAR_LITERAL: %c\n", yylval.cval);
  465.       break;
  466.     case STRING_LITERAL:
  467.       printf("STRING_LITERAL: %s\n", yylval.sval);
  468.       break;
  469.     case BINOP:
  470.       printf("BINOP: %d\n", yylval.op);
  471.       break;
  472.     }
  473.   }
  474. #endif /* LEXDEBUG */
  475. }
  476.  
  477. /*
  478.  *    static void initPaths()
  479.  *
  480.  * Description
  481.  *
  482.  *    Sets up the paths for the kernel source directory and for where the
  483.  *    saved Smalltalk binary image lives.  Uses environment variables
  484.  *    SMALLTALK_KERNEL and SMALLTALK_IMAGE if they are set, otherwise uses
  485.  *    the paths assigned in mstpaths.h.
  486.  *
  487.  */
  488. static void initPaths()
  489. {
  490.   if ((kernelFileDefaultPath = (char *)getenv("SMALLTALK_KERNEL")) == nil) {
  491.     kernelFileDefaultPath = KERNEL_PATH;
  492.   }
  493.  
  494.   if ((imageFileDefaultPath = (char *)getenv("SMALLTALK_IMAGE")) == nil) {
  495.     imageFileDefaultPath = IMAGE_PATH;
  496.   }
  497. }
  498.  
  499. static Boolean okToLoadBinary(imageFileName)
  500. char    *imageFileName;
  501. {
  502.   unsigned long    imageFileTime;
  503.   char        **fileNames, fullFileName[MAXPATHLEN],
  504.           fullImageName[MAXPATHLEN];
  505.  
  506.   findImageFile(imageFileName, fullImageName);
  507.   imageFileTime = getFileModifyTime(fullImageName);
  508.  
  509.   if ((long)imageFileTime == -1) { /* not found */
  510.     return (false);
  511.   }
  512.  
  513.   for (fileNames = standardFiles; *fileNames; fileNames++) {
  514.     findKernelFile(*fileNames, fullFileName);
  515.     if (imageFileTime < getFileModifyTime(fullFileName)) {
  516.       return (false);
  517.     }
  518.   }
  519.  
  520.   return (true);
  521. }
  522.  
  523. static unsigned long getFileModifyTime(fileName)
  524. char    *fileName;
  525. {
  526.   struct stat    st;
  527.  
  528.   if (stat(fileName, &st) < 0) {
  529.     return ((unsigned long) -1);
  530.   } else {
  531.     return (st.st_mtime);
  532.   }
  533. }
  534.  
  535. /*
  536.  *    static void loadStandardFiles()
  537.  *
  538.  * Description
  539.  *
  540.  *    Loads the kernel Smalltalk files.  It uses a vector of file names, and
  541.  *    loads each file individually.  To provide for greater flexibility, if a
  542.  *    one of the files exists in the current directory, that is used in
  543.  *    preference to one in the default location.  The default location can be
  544.  *    overridden at runtime by setting the SMALLTALK_KERNEL environment
  545.  *    variable. 
  546.  *
  547.  */
  548. static void loadStandardFiles()
  549. {
  550.   char        **fileNames, fullFileName[MAXPATHLEN];
  551.   
  552.   for (fileNames = standardFiles; *fileNames; fileNames++) {
  553.     findKernelFile(*fileNames, fullFileName);
  554.     if (!processFile(fullFileName, true)) {
  555.       fprintf(stderr,
  556.           "Can't find system file '%s', proceeding without it.\n",
  557.           fullFileName);
  558.     }
  559.   }
  560. }
  561.  
  562.  
  563. /*
  564.  *    static void findKernelFile(fileName, fullFileName)
  565.  *
  566.  * Description
  567.  *
  568.  *    Attempts to find a viable kernel Smalltalk file (.st file).  First
  569.  *    tries the current directory to allow for overriding installed kernel
  570.  *    files.  If that isn't found, the full path name of the installed kernel
  571.  *    file is stored in fullFileName.  Note that the directory part of the
  572.  *    kernel file name in this second case can be overridden by defining the
  573.  *    SMALLTALK_KERNEL environment variable to be the directory that should
  574.  *    serve as the kernel directory instead of the installed one.
  575.  *
  576.  * Inputs
  577.  *
  578.  *    fileName: 
  579.  *        A simple file name, sans directory.
  580.  *    fullFileName: 
  581.  *        The file name to use for the particular kernel file is returned
  582.  *        in this variable (which must be a string large enough for any
  583.  *        file name).  If there is a file in the current directory with
  584.  *        name "fileName", that is returned; otherwise the kernel path is
  585.  *        prepended to fileName (separated by a slash, of course) and
  586.  *        that is stored in the string pointed to by "fullFileName".
  587.  *
  588.  */
  589. static void findKernelFile(fileName, fullFileName)
  590. char *fileName, *fullFileName;
  591. {
  592.   if (access(fileName, R_OK) == 0) {
  593.     strcpy(fullFileName, fileName);
  594.   } else {
  595.     sprintf(fullFileName, "%s/%s", kernelFileDefaultPath, fileName);
  596.   }
  597. }
  598.  
  599.  
  600. static void loadUserInitFile()
  601. {
  602.   char        fileName[MAXPATHLEN], *home;
  603.  
  604.   if ((home = (char *)getenv("HOME")) != nil) {
  605.     sprintf(fileName, "%s/%s", home, INIT_FILE_NAME);
  606.     processFile(fileName, quietExecution);
  607.   }
  608. }
  609.  
  610. static Boolean processFile(fileName, quiet)
  611. char    *fileName;
  612. Boolean    quiet;
  613. {
  614.   FILE        *file;
  615.  
  616.   file = fopen(fileName, "r");
  617.   if (file == NULL) {
  618.     return (false);
  619.   }
  620.  
  621.   if (verbose) {
  622.     printf("Processing %s\n", fileName);
  623.   }
  624.  
  625.   quietExecution = quiet;
  626.   initLexer(false);
  627.   pushUNIXFile(file, fileName);
  628.   yyparse();
  629.   popStream(true);
  630.  
  631.   return (true);
  632. }
  633.  
  634. /*
  635.  *    static void findImageFile(fileName, fullFileName)
  636.  *
  637.  * Description
  638.  *
  639.  *    Attempts to find a viable Smalltalk image file.  First
  640.  *    tries the current directory to allow for overriding installed image
  641.  *    files.  If that isn't found, the full path name of the installed image
  642.  *    file is stored in fullFileName.  Note that the directory part of the
  643.  *    image file name in this second case can be overridden by defining the
  644.  *    SMALLTALK_IMAGE environment variable to be the directory that should
  645.  *    serve as the image directory instead of the installed one.
  646.  *
  647.  * Inputs
  648.  *
  649.  *    fileName: 
  650.  *        A simple file name, sans directory.
  651.  *    fullFileName: 
  652.  *        The file name to use for the particular image file is returned
  653.  *        in this variable (which must be a string large enough for any
  654.  *        file name).  If there is a file in the current directory with
  655.  *        name "fileName", that is returned; otherwise the kernel path is
  656.  *        prepended to fileName (separated by a slash, of course) and
  657.  *        that is stored in the string pointed to by "fullFileName".
  658.  *
  659.  */
  660. void findImageFile(fileName, fullFileName)
  661. char *fileName, *fullFileName;
  662. {
  663.   if (access(fileName, R_OK) == 0) {
  664.     strcpy(fullFileName, fileName);
  665.   } else {
  666.     sprintf(fullFileName, "%s/%s", imageFileDefaultPath, fileName);
  667.   }
  668. }
  669.  
  670.  
  671. /*
  672.  *    static void parseArgs(argc, argv)
  673.  *
  674.  * Description
  675.  *
  676.  *    This routine scans the command line arguments, accumulating information
  677.  *    and setting flags.  This will probably be replaced by getopt in a
  678.  *    future version of Smalltalk.
  679.  *
  680.  * Inputs
  681.  *
  682.  *    argc  : The number of arguments present
  683.  *    argv  : Vector of strings that are the arguments.
  684.  *
  685.  */
  686. static void parseArgs(argc, argv)
  687. int    argc;
  688. char    **argv;
  689. {
  690.   char        **hp, **av;
  691.   char        *flags;
  692.  
  693.   static char    *helpText[] = {
  694. "GNU Smalltalk usage:",
  695. "",
  696. "    mst [ flag ... ] [ file ...]",
  697. "",
  698. "Flags can appear either as -xyz or as -x -y -z.  The currently",
  699. "defined set of flags is:",
  700. "  -c\tDump core on fatal signal",
  701. "  -d\tTrace compilation of user specified files",
  702. "  -D\tTrace compilation of kernel and user files",
  703. "  -e\tTrace execution of files specified on command line",
  704. "  -E\tTrace execution of kernel and user files",
  705. "  -H -h -?  Print this message and exit",
  706. "  -i\tIgnore the image file; rebuild it from scratch",
  707. "  -I file\tUse 'file' as the image file, instead of 'mst.im'",
  708. "  -p\tRun Smalltalk as a 'process', i.e. from within GNU Emacs",
  709. "  -q\tRun Smalltalk without printing execution information",
  710. "  -r\tRun in regression test mode (printed messages are made constant)",
  711. "  -v\tPrint the Smalltalk version number",
  712. "  -V\tEnable verbose mode",
  713. "  -y\tTurn on debugging in the parser",
  714. "  - --\tRead input from standard input explicitly",
  715. "",
  716. "Files are loaded one after the other.  After the last one is loaded,",
  717. "Smalltalk will exit.  If no files are specified, Smalltalk reads from",
  718. "the terminal, with prompts.",
  719. NULL
  720. };
  721.  
  722.  
  723.   for ( ; *++argv; ) {
  724.     if (argv[0][0] == '-') {
  725.       for (flags = &argv[0][1]; *flags; flags++) {
  726.     switch (*flags) {
  727.     case 'c':
  728.       makeCoreFile = true;
  729.       break;
  730.     case 'D':
  731.       traceKernelDeclarations = true; /* fall thru */
  732.     case 'd':
  733.       declareTracing = true;
  734.       break;
  735.     case 'E':
  736.       traceKernelExecution = true; /* fall thru */
  737.     case 'e':
  738.       executionTracing = true;
  739.       break;
  740.     case 'h': case 'H': case '?':
  741.     default:
  742.       for (hp = helpText; *hp != NULL; hp++) {
  743.         printf("%s\n", *hp);
  744.       }
  745.           exit(0);
  746.     case 'I':
  747.       binaryImageName = argv[1];
  748.       for (av = argv+1; *av; av++) {    /* remove this argument */
  749.         *av = *(av+1);
  750.       }
  751.       break;
  752.     case 'i':
  753.       ignoreImage = true;
  754.       break;
  755.     case 'p':
  756.       emacsProcess = true;
  757.       break;
  758.     case 'q':
  759.       runQuietly = true;
  760.       break;
  761.     case 'r':
  762.       regressionTesting = true;
  763.       break;
  764.     case 'V':
  765.       verbose = true;
  766.       break;
  767.     case 'v':
  768.       printf("GNU Smalltalk version %s\n", versionString);
  769.       printf("Copyright (C) 1990, 1991 Free Software Foundation, Inc.\n");
  770.       printf("Written by Steve Byrne.\n");
  771.       printf("Using kernel path: %s\n", kernelFileDefaultPath);
  772.       printf("Using image path : %s\n", imageFileDefaultPath);
  773.       break;
  774.     case 'y':
  775.       yydebug = 1;
  776.       break;
  777.     case '-':        /* this means standard input, so it's ok */
  778.       break;
  779.     }
  780.       }
  781.     }
  782.   }
  783.  
  784.   if (regressionTesting) {
  785.     traceKernelDeclarations = declareTracing = false;
  786.     traceKernelExecution = executionTracing = false;
  787.     verbose = false;
  788.   }
  789. }
  790.  
  791. static void makeVersionString()
  792. {
  793.   if (sysVersEdit != 0) {
  794.     sprintf(versionString, "%d.%d.%d", sysVersMajor, sysVersMinor,
  795.         sysVersEdit);
  796.   } else {
  797.     sprintf(versionString, "%d.%d", sysVersMajor, sysVersMinor);
  798.   }
  799. }
  800.